package pl.drypisy;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import android.util.Log;

/**
 * @author Michal Drobniak
*/
public class XMLParser {
	
	// All static variables
	String xmlName;// = "/sdcard/trasa_test.xml";
	// XML node keys
	static final String KEY_ROUTE = "route"; // parent node
	static final String KEY_TITLE = "name";
	static final String KEY_ABOUT = "about";
	
	static final String KEY_CHECKPOINTLIST = "checkpointlist";
	static final String KEY_CHECKPOINT = "checkpoint";
	static final String KEY_CHTITLE= "title";
	static final String KEY_LATITUDE = "latitude";
	static final String KEY_LONGITUDE = "longitude";
	static final String KEY_TASK = "task";
	static final String KEY_ANSWER = "answer";
	static final String KEY_HINT = "hint";

	private XMLParser parser; //class XMLParse(this) for getRouteData() & getCheckpoints() methods
	private Document doc;
	
	/*
	 * parser for local xml file
	 */
	public XMLParser(String xmlPath){
		xmlName=xmlPath;
		parser = this;
		doc = parser.getDomElement(xmlName); // getting DOM element
	}
	
	/*
	 * parser for passed input stream 
	 */
	public XMLParser(InputStream stream){
		xmlName="";
		parser=this;
		doc = parser.getDomElementFromInputStream(stream);
	}
	
	
	public ArrayList<String> getRouteData(){
		NodeList nl = doc.getElementsByTagName(KEY_ROUTE);
		
		String title="",about="";
		
		ArrayList<String> routeData= new ArrayList<String>();
		
		// looping through all item nodes <item>
		for (int i = 0; i < nl.getLength(); i++) {
			Element e = (Element) nl.item(i);
		    title = parser.getValue(e, KEY_TITLE); //  child value
		    about = parser.getValue(e, KEY_ABOUT); //  child value
		    routeData.add(title);
			routeData.add(about);
		}
		return routeData;
	}
	
	public ArrayList<HashMap<String, String>> getCheckpoints(){
		NodeList chPointNL = doc.getElementsByTagName(KEY_CHECKPOINT);
		NodeList hintNl;  //hints list
		
		ArrayList<HashMap<String, String>> checkpoints= new ArrayList<HashMap<String, String>>();
		
		for (int i=0; i<chPointNL.getLength(); i++) {
			Element e = (Element) chPointNL.item(i);	
			HashMap<String, String> cp=new HashMap<String, String>();
			
		    cp.put("name",parser.getValue(e, KEY_CHTITLE));
		    cp.put("lat",parser.getValue(e, KEY_LATITUDE));
		    cp.put("lon",parser.getValue(e, KEY_LONGITUDE));
		    cp.put("task",parser.getValue(e, KEY_TASK));
		    cp.put("answer", parser.getValue(e, KEY_ANSWER));
		    hintNl = e.getElementsByTagName(KEY_HINT);
		    
		    for(int j=1; j<=hintNl.getLength(); j++){
		    	Element e2 = (Element) hintNl.item(j-1);	//hint numbers from 1 but elements from 0
		    	cp.put(KEY_HINT+j, parser.getElementValue(e2));
		    }
		   
		    checkpoints.add(cp);
		}
		Log.d("parser","checkpointy inserted");
		return checkpoints;
	}
	
	/*
	 * build document from local xml file
	 */
	public Document getDomElement(String xml){
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = null;
		try {
		    builder = builderFactory.newDocumentBuilder();
		} catch (ParserConfigurationException e) {
		    e.printStackTrace();  
		}
		
		Document doc = null;
		try {
			File file=new File(xml);
		    doc = builder.parse(new FileInputStream(file));
		} catch (SAXException e) {
		    e.printStackTrace();
		} catch (IOException e) {
		    e.printStackTrace();
		}
		
		return doc;
    }
	
	/*
	 * build document from passed input stream
	 */
	public Document getDomElementFromInputStream(InputStream is){
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = null;
		try {
		    builder = builderFactory.newDocumentBuilder();
		} catch (ParserConfigurationException e) {
		    e.printStackTrace();  
		}
		
		Document doc = null;
		try {
		    doc = builder.parse(is);
		} catch (SAXException e) {
		    e.printStackTrace();
		} catch (IOException e) {
		    e.printStackTrace();
		}
		
		return doc;
	}
	
	public String getValue(Element item, String str) {
	    NodeList n = item.getElementsByTagName(str);
	    return this.getElementValue(n.item(0));
	}
	 
	public final String getElementValue( Node elem ) {
         Node child;
         if( elem != null){
             if (elem.hasChildNodes()){
                 for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){
                     if( child.getNodeType() == Node.TEXT_NODE  ){
                         return child.getNodeValue();
                     }
                 }
             }
         }
         return "";
	  }
	
	public final String getElementVal(Node e){
		if(e!=null){
			return e.getNodeName();
		}
		return "";
	}
}
